#ifndef __INCLUDED_CBL_ATOMIC_OPERATIONS_H__
#error "CBL_AtomicOperations.hpp must not be used directly. Use CBL_AtomicOperations.h instead."
#else
#ifndef __INCLUDED_CBL_ATOMIC_OPERATIONS_HPP__
#define __INCLUDED_CBL_ATOMIC_OPERATIONS_HPP__

#ifdef CB_WINDOWS

#include "CBL_Windows.h"

template <typename TType>
CB_FORCEINLINE void CB_INLINE_ATTR ThreadAtomicIncrement(volatile TType& _rValue)
{
	_rValue = InterlockedIncrement(&_rValue);
}

// ---------------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE void CB_INLINE_ATTR ThreadAtomicDecrement(volatile TType& _rValue)
{
	_rValue = InterlockedDecrement(&_rValue);
}

// ---------------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE TType CB_INLINE_ATTR ThreadAtomicCompareAndSwap(volatile TType& _rValue, TType _CmpValue, TType _SetValue)
{
	return InterlockedCompareExchange(&_rValue, _SetValue, _CmpValue);
}

#elif defined(CB_GCC)

template <typename TType>
CB_FORCEINLINE void CB_INLINE_ATTR ThreadAtomicIncrement(volatile TType& _rValue)
{
	__sync_fetch_and_add(&_rValue, (TType)1);
}

// ---------------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE void CB_INLINE_ATTR ThreadAtomicDecrement(volatile TType& _rValue)
{
	__sync_fetch_and_sub(&_rValue, (TType)1);
}

// ---------------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE TType CB_INLINE_ATTR ThreadAtomicCompareAndSwap(volatile TType& _rValue, TType _CmpValue, TType _SetValue)
{
	return __sync_val_compare_and_swap(&_rValue, _CmpValue, _SetValue);
}

#else

#error "Unsupported compiler. AtomicOperations only implemented with Windows or GCC."

#endif

#endif
#endif